#!/usr/bin/env python3
"""
Author: Haoran Peng
Email: gavinsweden@gmail.com
"""

from copy import deepcopy
from typing import Dict, List, Set, Tuple

from .agent import Agent

"""
Emulated dictionary of dictionaries
"""


class Constraints:
    def __init__(self):
        #                                   time,         obstacles
        self.agent_constraints: Dict[Agent : Dict[int, Set[Tuple[int, int]]]] = dict()
        self.agent_speed_control: Dict[Agent : Set[Tuple[int, int, int, int, int]]] = (
            dict()
        )

    """
    Deepcopy self with additional constraints
    """

    def fork(
        self,
        agent: Agent,
        agent_2: Agent,
        obstacle: Tuple[int, int],
        start: int,
        end: int,
        conflict_space: List[
            Tuple[
                str, str, Tuple[int, int, int, int, int], Tuple[int, int, int, int, int]
            ]
        ],
        caclulate_type: str,
    ) -> "Constraints":
        """'
        增加从start到end的点约束，控制agent不能经过obstacle，这是对于点的控制
        目前需要有减速带和加速带，而不是单独的一个点
        """
        agent_constraints_copy = deepcopy(self.agent_constraints)
        for time in range(start, end):
            agent_constraints_copy.setdefault(agent, dict()).setdefault(
                time, set()
            ).add(obstacle)
        if conflict_space[0] == "point":
            agent_speed_control = deepcopy(self.agent_speed_control)
            if conflict_space[1] == caclulate_type:
                agent_speed_control.setdefault(agent, set()).add(conflict_space[3])
                agent_speed_control.setdefault(agent_2, set()).add(conflict_space[2])
            else:
                agent_speed_control.setdefault(agent, set()).add(conflict_space[2])
                agent_speed_control.setdefault(agent_2, set()).add(conflict_space[3])
        elif conflict_space[0] == "parallel":
            agent_speed_control = deepcopy(self.agent_speed_control)
            if conflict_space[1] == caclulate_type:
                agent_speed_control.setdefault(agent, set()).add(conflict_space[2])
                agent_speed_control.setdefault(agent_2, set()).add(conflict_space[3])
            else:
                agent_speed_control.setdefault(agent, set()).add(conflict_space[3])
                agent_speed_control.setdefault(agent_2, set()).add(conflict_space[2])
        new_constraints = Constraints()
        new_constraints.agent_constraints = agent_constraints_copy
        new_constraints.agent_speed_control = agent_speed_control
        return new_constraints

    def setdefault(self, key, default):
        return self.agent_constraints.setdefault(key, default)

    def setdefault_speed(self, key, default):
        return self.agent_speed_control.setdefault(key, default)

    def __getitem__(self, agent):
        return self.agent_constraints[agent]

    def __iter__(self):
        for key in self.agent_constraints:
            yield key

    def __str__(self):
        return str(self.agent_constraints)
